﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;

namespace RemoteHardwareMonitor
{
    /// <summary>
    /// Very basic web server to server up the html+javascript page displaying hardware data.
    /// </summary>
    class WebServer
    {
        
        string responseString;
        bool go;

        public WebServer()
        {
                    if (!HttpListener.IsSupported)
                    {
                        Console.WriteLine ("Windows XP SP2 or Server 2003 or later is required to use the HttpListener class.");
                        return;

                    }

                    responseString = loadHTML();
        }


        public void RunServer()
        {
            // setting an actual IP here fails with a http 503 response for some reason.
            // TODO: allow a different port to be configured or passed in as a paramater.
            HttpListener listener = new HttpListener();
            string prefix = "http://+:8080/hardwaremonitor/";
            go = true;
            listener.Prefixes.Add(prefix);
            listener.Start();
            Console.WriteLine("listening...");
            while (go)
            {
                // using async calls so multiple clients can be served
                IAsyncResult result = listener.BeginGetContext(new AsyncCallback(listenerCallback), listener);
                // use a wait handle to prevent this thread from terminating
                // while the asynchronous operation completes.
                result.AsyncWaitHandle.WaitOne();
            }

            listener.Close();
            Console.WriteLine("listener closed.");
        }


        public void Stop()
        {
            go = false;
        }

        private string loadHTML()
        {
            try
            {
                StringBuilder sb = new StringBuilder();
                //TODO: generate this file by applying XSLT to the doc created by SensorsToXML
                using (StreamReader sr = new StreamReader("../../testJS.html"))
                {
                    

                    String line;
                    // Read and display lines from the file until the end of
                    // the file is reached.
                    while ((line = sr.ReadLine()) != null)
                    {
                        sb.Append(line);
                        sb.Append("\n");
                        //Console.WriteLine(line);
                    }
                }
#if DEBUG
                StreamWriter w = new StreamWriter("test.html");
                w.Write(sb.ToString());
                w.Close();
#endif
                return sb.ToString();
            }
            catch (Exception e)
            {
                Console.WriteLine("The file could not be read:");
                Console.WriteLine(e.Message);
                return "<HTML><BODY> The file could not be read: <p>" +  e.Message + "</p> </BODY></HTML>";
            }
        }

        private void listenerCallback(IAsyncResult result)
        {
            HttpListener listener = (HttpListener)result.AsyncState;
            HttpListenerContext context = listener.EndGetContext(result);
            HttpListenerRequest request = context.Request;
            // Obtain a response object.
            HttpListenerResponse response = context.Response;
            byte[] buffer = System.Text.Encoding.UTF8.GetBytes(responseString);
            // Get a response stream and write the response to it.
            response.ContentLength64 = buffer.Length;
            System.IO.Stream output = response.OutputStream;
            output.Write(buffer, 0, buffer.Length);
            // You must close the output stream.
            output.Close();
        }
    }
}
